<style scoped>
/* 触发按钮样式 */
.selected-area {
  width: 10rem;
  background-color: #fff;
  border: 1px solid #eee;
  border-radius: 8px;
  font-size: 16px;
  color: #333;
  text-align: left;
}

.placeholder {
  color: #999;
}

/* 遮罩层 */
.picker-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 1000;
}

/* 选择器面板 */
.picker-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #fff;
  border-radius: 16px 16px 0 0;
  z-index: 1001;
}

/* 头部样式 */
.picker-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px;
  border-bottom: 1px solid #eee;
}

.picker-btn {
  padding: 8px 15px;
  background: none;
  border: none;
  font-size: 16px;
  cursor: pointer;
}

.cancel {
  color: #999;
}

.confirm {
  color: #1677ff;
}

.picker-title {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: #333;
}

/* 内容区域 */
.picker-content {
  display: flex;
  height: 260px;
  overflow: hidden;
  position: relative;
}

.picker-col {
  flex: 1;
  height: 100%;
  overflow: hidden;
  position: relative;
}

.picker-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  transition: transform 0.1s ease-out;
  text-align: center;
  padding-top: 110px;
  /* 中间选中区域的位置 */
  padding-bottom: 110px;
}

.picker-col li {
  height: 44px;
  line-height: 44px;
  font-size: 16px;
  color: #999;
}

.picker-col li.active {
  color: #333;
  font-weight: 500;
}

/* 选中指示器 */
.picker-indicator {
  position: absolute;
  top: 180px;
  left: 0;
  right: 0;
  height: 44px;
  pointer-events: none;
  box-sizing: border-box;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
}
</style>
<template>
  <div class="area-picker-container">
    <!-- 触发按钮 -->
    <!-- 选择器弹窗 -->
    <div class="picker-mask" v-if="showDefault" @click="hidePicker"></div>
    <div class="picker-panel" v-if="showDefault">
      <!-- 顶部操作栏 -->
      <div class="picker-header">
        <button class="picker-btn cancel" @click="hidePicker">取消</button>
        <h3 class="picker-title">选择地区</h3>
        <button class="picker-btn confirm" @click="confirmSelection">确认</button>
      </div>

      <!-- 滚动选择区域 -->
      <div class="picker-content">
        <div class="picker-col" ref="provinceCol">
          <ul @touchstart="onTouchStart('province', $event)" @touchmove="onTouchMove('province', $event)"
            @touchend="onTouchEnd('province')">
            <li v-for="(item, index) in provinces" :key="index" :class="{ active: index === provinceIndex }">{{
              item.name }}</li>
          </ul>
        </div>
        <div class="picker-col" ref="cityCol">
          <ul @touchstart="onTouchStart('city', $event)" @touchmove="onTouchMove('city', $event)"
            @touchend="onTouchEnd('city')">
            <li v-for="(item, index) in citys" :key="index" :class="{ active: index === cityIndex }">{{
              item.name }}</li>
          </ul>
        </div>
        <div class="picker-col" ref="districtCol">
          <ul @touchstart="onTouchStart('district', $event)" @touchmove="onTouchMove('district', $event)"
            @touchend="onTouchEnd('district')">
            <li v-for="(item, index) in formatDistricts" :key="index" :class="{ active: index === districtIndex }">{{
              item }}</li>
          </ul>
        </div>
      </div>
      <!-- 选中指示器 -->
      <div class="picker-indicator"></div>
    </div>
  </div>
</template>

<script>
import cityData from '../../city/city.json'
export default {
  props: {
    // 显示默认值
    showDefault: {
      type: Boolean,
      default: false
    },
    // 选中值
    selectedAreaProvince: {
      type: String,
      default: ''
    },
    selectedAreaCity: {
      type: String,
      default: ''
    },
    selectedAreaDistrict: {
      type: String,
      default: ''
    },
  },
  emits: [
    'update:showDefault',
    'update:selectedAreaProvince',
    'update:selectedAreaCity',
    'update:selectedAreaDistrict'
  ],
  data() {
    return {
      // 显示控制
      isPickerVisible: false,
      // 选中值
      selectedProvince: '',
      selectedCity: '',
      selectedDistrict: '',

      // 临时选中值
      tempProvince: '',
      tempCity: '',
      tempDistrict: '',

      // 索引控制
      provinceIndex: 0,
      cityIndex: 0,
      districtIndex: 0,

      // 滚动状态
      touchState: {
        province: {
          startY: 0,
          moveY: 0,
          currentY: 0,
          isMoving: false,
          itemHeight: 44 // 每个选项的高度
        },
        city: {
          startY: 0,
          moveY: 0,
          currentY: 0,
          isMoving: false,
          itemHeight: 44
        },
        district: {
          startY: 0,
          moveY: 0,
          currentY: 0,
          isMoving: false,
          itemHeight: 44
        }
      },
    };
  },

  computed: {
    // 省份列表
    provinces() {
      return cityData;
    },
    // 根据选中的省份获取城市列表
    // 根据选中的省份索引获取对应的城市列表
    // 若省份列表存在且省份索引有效，则返回对应省份的城市列表；否则返回空数组
    citys() {
      // 检查省份列表是否有数据且省份索引有效
      if (this.provinces.length && this.provinceIndex >= 0) {
        // 返回对应省份的城市列表，若不存在则返回空数组
        return this.provinces[this.provinceIndex].cities || [];
      }
      // 省份列表为空或省份索引无效时，返回空数组
      return [];
    },

    // 根据选中的城市获取区县列表
    districts() {
      if (this.citys.length && this.cityIndex >= 0) {
        return this.citys[this.cityIndex].districts || [];
      }
      return [];
    },

    // 格式化区县列表，确保渲染正确
    formatDistricts() {
      return this.districts.map(district => {
        if (typeof district === 'string') {
          return district;
        }
        return district.name || '';
      });
    }
  },

  watch: {
    // 监听省份变化，重置城市和区县索引
    provinceIndex(newVal) {
      this.cityIndex = 0;
      this.districtIndex = 0;
      this.updateScrollPosition('city');
      this.updateScrollPosition('district');
    },
    // 监听城市变化，重置区县索引
    cityIndex(newVal) {
      this.districtIndex = 0;
      this.updateScrollPosition('district');
    },
    // 监听props变化，更新选中值
    selectedAreaProvince(newVal) {
      if (newVal) {
        this.selectedProvince = newVal;
        this.updateIndexByValue('province', newVal);
      }
    },
    selectedAreaCity(newVal) {
      if (newVal) {
        this.selectedCity = newVal;
        this.updateIndexByValue('city', newVal);
      }
    },
    selectedAreaDistrict(newVal) {
      if (newVal) {
        this.selectedDistrict = newVal;
        this.updateIndexByValue('district', newVal);
      }
    }
  },

  mounted() {
    this.$nextTick(() => {
      // 遍历省份、城市、区县三种类型，动态获取每种类型对应列表项的高度
      ['province', 'city', 'district'].forEach(type => {
        // 获取当前类型对应列的第一个列表项元素
        const element = this.$refs[`${type}Col`]?.querySelector('li');
        // 若元素存在，则更新触摸状态中该类型的列表项高度
        if (element) {
          this.touchState[type].itemHeight = element.offsetHeight;
        }
      });

      // 初始化选中值
      if (this.selectedAreaProvince) {
        this.updateIndexByValue('province', this.selectedAreaProvince);
      }
      if (this.selectedAreaCity) {
        this.updateIndexByValue('city', this.selectedAreaCity);
      }
      if (this.selectedAreaDistrict) {
        this.updateIndexByValue('district', this.selectedAreaDistrict);
      }
    });
  },

  methods: {
    // 显示选择器
    showPicker() {
      this.isPickerVisible = true;
      // 记录当前选中值，用于取消时恢复
      this.tempProvince = this.selectedProvince;
      this.tempCity = this.selectedCity;
      this.tempDistrict = this.selectedDistrict;
    },

    // 隐藏选择器
    hidePicker() {
      // 1. 重置滚动状态（避免触摸事件导致的状态错乱）
      ['province', 'city', 'district'].forEach(type => {
        this.touchState[type].isMoving = false;
        this.touchState[type].moveY = 0;
      });
      // 2. 恢复选中值
      this.selectedProvince = this.tempProvince;
      this.selectedCity = this.tempCity;
      this.selectedDistrict = this.tempDistrict;
      // 3. 更新内部状态
      this.isPickerVisible = false;
      // 4. 触发 .sync 期望的事件名（update:Props名）
      this.$emit('update:showDefault', false);
    },

    // 确认选择
    confirmSelection() {
      // 更新选中的省份名称，若未选中则置空
      this.selectedProvince = this.provinces[this.provinceIndex]?.name || '';
      // 更新选中的城市名称，若未选中则置空
      this.selectedCity = this.citys[this.cityIndex]?.name || '';
      // 更新选中的区县名称，若未选中则置空
      this.selectedDistrict = this.formatDistricts[this.districtIndex] || '';
      // 更新内部状态
      this.isPickerVisible = false;
      // 触发自定义事件，传递选中结果
      this.$emit('update:selectedAreaProvince', this.selectedProvince);
      this.$emit('update:selectedAreaCity', this.selectedCity);
      this.$emit('update:selectedAreaDistrict', this.selectedDistrict);
      this.$emit('update:showDefault', false);

    },

    // 触摸开始
    onTouchStart(type, e) {
      e.preventDefault();
      this.touchState[type].startY = e.touches[0].clientY;
      this.touchState[type].isMoving = true;
    },

    // 触摸移动
    onTouchMove(type, e) {
      e.preventDefault();
      if (!this.touchState[type].isMoving) return;

      const currentY = e.touches[0].clientY;
      this.touchState[type].moveY = currentY - this.touchState[type].startY;
      // 计算新的位置并应用
      const element = this.$refs[`${type}Col`]?.querySelector('ul');
      if (!element) return;

      // 计算新的 Y 轴位置，将当前位置与本次触摸移动的距离相加
      const newY = this.touchState[type].currentY + this.touchState[type].moveY;

      // 限制滚动范围
      const maxScroll = 0;
      const minScroll = -Math.abs(((this[`${type}s`] || []).length - 1) * this.touchState[type].itemHeight);
      const limitedY = Math.max(Math.min(newY, maxScroll), minScroll);
      //  const limitedY = Math.max(minScroll, Math.min(currentY, maxScroll));
      element.style.transform = `translateY(${limitedY}px)`;
    },

    // 触摸结束
    onTouchEnd(type) {
      if (!this.touchState[type].isMoving) return;

      const element = this.$refs[`${type}Col`]?.querySelector('ul');
      if (!element) return;

      const finalY = this.touchState[type].currentY + this.touchState[type].moveY;

      // 计算最终应该停留的位置
      const itemHeight = this.touchState[type].itemHeight;
      let index = Math.round(-finalY / itemHeight);

      // 限制索引范围
      const maxIndex = (this[`${type}s`] || []).length - 1;
      index = Math.max(0, Math.min(index, maxIndex));

      // 更新位置和索引
      const newY = -index * itemHeight;
      element.style.transform = `translateY(${newY}px)`;
      this[`${type}Index`] = index;

      // 保存当前位置状态
      this.touchState[type].currentY = newY;
      this.touchState[type].isMoving = false;
      this.touchState[type].moveY = 0;
    },

    // 更新滚动位置
    updateScrollPosition(type) {
      const element = this.$refs[`${type}Col`]?.querySelector('ul');
      if (!element) return;

      const index = this[`${type}Index`];
      const newY = -index * this.touchState[type].itemHeight;

      element.style.transform = `translateY(${newY}px)`;
      this.touchState[type].currentY = newY;
    },

    // 根据值更新索引
    updateIndexByValue(type, value) {
      let list;
      if (type === 'province') {
        list = this.provinces;
      } else if (type === 'city') {
        list = this.citys;
      } else if (type === 'district') {
        list = this.formatDistricts;
      }

      if (list && list.length > 0) {
        const index = list.findIndex(item => {
          if (typeof item === 'string') {
            return item === value;
          }
          return item.name === value;
        });

        if (index !== -1) {
          this[`${type}Index`] = index;
          this.$nextTick(() => {
            this.updateScrollPosition(type);
          });
        }
      }
    }
  }
};
</script>